﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UnityScriptEngine;
using System.Speech.Synthesis;
using MetriCam;

namespace MBB_Payroll_Terminal
{
    public partial class frmDTR : Form
    {
        Timer sys = new Timer();
        Timer tmr = new Timer();
        bool isTimeIn = true;
        bool isShow = false;
        UnityProcessor proc = new UnityProcessor();
        UnityScript empProf = new UnityScript("GETPROF", 5);
        UnityScript dtr = new UnityScript("ADD_DTR",new object[]{"fEmpNo", "fDate", "fTimeIn", "fTimeOut"});
        Threader t = new Threader();
        SpeechSynthesizer sapi = new SpeechSynthesizer();
        string curName = "";
        string curID = "";
        string curDate = "";
        string curTime = "";
        bool curFound = false;
        int errType = 0; //0-No Error, 1-Already have time in, 2-Already Have time out
        WebCam cam = new WebCam();
        Bitmap bmp;
        public frmDTR()
        {
            InitializeComponent();
            InitializeFrameSliderForm();
        }
        private void InitializeForm()
        {
            
            txtDate.Text = DateTime.Now.ToLongDateString();
            txtTime.Text = DateTime.Now.ToString("hh:mm:ss tt");
            

            sys.Interval = 100;
            sys.Enabled = true;
            sys.Tick += new EventHandler(sys_Tick);
            tmr.Interval = 3000;
            tmr.Enabled = false;
            tmr.Tick += new EventHandler(tmr_Tick);

            btnIn.Click += new EventHandler(btnIn_Click);
            btnOut.Click += new EventHandler(btnOut_Click);
            btnShow.Click += new EventHandler(btnShow_Click);
            txtID.KeyPress += new KeyPressEventHandler(txtID_KeyPress);
            proc.ProcessCompleted += new ProcessHandler(proc_ProcessCompleted);
            proc.ProcessError += new ProcessHandler(proc_ProcessError);
            sapi.Rate = -2;

            bmp = (Bitmap)picCurrent.Image;
        }

        void tmr_Tick(object sender, EventArgs e)
        {
            tmr.Enabled = false;
            pnlPop.Visible = false;
        }
        void txtID_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)13)
            {
                //Do DTR here
                empProf.Script_Clear();
                empProf.Script_Add(Script.PROC_NAME, "GETPROF");
                empProf.Script_Add(Script.LFFPU_READ, Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\employee.elt", "elayorbulc");
                proc.Run(empProf);
                curID = txtID.Text;
                //Reset contents and set focus.
                txtID.Text = "";
                txtID.Focus();

                
            }
        }

        void btnShow_Click(object sender, EventArgs e)
        {
            SetShow();
        }
        void btnOut_Click(object sender, EventArgs e)
        {
            SetOut();
        }
        void btnIn_Click(object sender, EventArgs e)
        {
            SetIn();
        }
        void sys_Tick(object sender, EventArgs e)
        {
            txtDate.Text = DateTime.Now.ToLongDateString();
            txtTime.Text = DateTime.Now.ToString("hh:mm:ss tt");
            picStream.Image = LiveStream();
        }

        public void SetIn()
        {
            btnIn.BackColor = Color.Green;
            btnOut.BackColor = Color.Gray;
            btnShow.BackColor = Color.Gray;
            isTimeIn = true;
            isShow = false;
            txtID.Focus();
        }
        public void SetOut()
        {
            btnIn.BackColor = Color.Gray;
            btnOut.BackColor = Color.Green;
            btnShow.BackColor = Color.Gray;
            isTimeIn = false;
            isShow = false;
            txtID.Focus();
        }
        public void SetShow()
        {
            btnIn.BackColor = Color.Gray;
            btnOut.BackColor = Color.Gray;
            btnShow.BackColor = Color.Green;
            isTimeIn = false;
            isShow = true;
            txtID.Focus();
        }
        public void IDFocus()
        {
            txtID.Focus();
        }
        void CheckProfile(string empno)
        {
            DataTable tmp = empProf.ToDataTable();
            curFound = false;
            for (int i = 0; i < tmp.Rows.Count; i++)
            {
                if (empno.Equals(tmp.Rows[i][0].ToString()))
                {
                    curName = tmp.Rows[i][1].ToString();
                    curDate = DateTime.Now.ToString("yyyy-MM-dd");
                    curTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                    curFound = true;
                    break;
                }
            }
        }
        string dtrfile = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\MBB Terminal Data\\dtr.uff";
        //string dtrfile = "D:\\dtr.uff";
        void OpenDTR()
        {
            if (System.IO.File.Exists(dtrfile))
            {
                dtr.Script_Clear();
                dtr.Script_Add(Script.PROC_NAME, "OPENDTR");        
                dtr.Script_Add(Script.LFFPU_READ, dtrfile, "elayorbulc");
                proc.Run(dtr);
            }
            else
            {
                if (!System.IO.Directory.Exists(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\MBB Terminal Data\\"))
                    System.IO.Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\MBB Terminal Data\\");

                dtr.Script_Clear();
                dtr.Script_Add(Script.PROC_NAME, "OPENDTR");
                dtr.Desc_FileTitle = "MBB_DTR_FILE";
                dtr.Desc_MetaData = "MBB Daily Time Record File";
                dtr.Script_Add(Script.LFFPU_WRITE, dtrfile, "elayorbulc");
                proc.Run(dtr);
            }
        }
        /*void DoDTR()
        {
            DataTable tmp = dtr.ToDataTable();
            UnityElement dt =new UnityElement(dtr.Desc_Fields());
            bool datefound = false;
            int dateindex = 0;
            if (isTimeIn)
            {
                for (int i = 0; i < tmp.Rows.Count; i++)
                {
                    if (tmp.Rows[i][1].ToString().Equals(curDate) && tmp.Rows[i][0].ToString().Equals(curID))
                    {
                        datefound = true;
                        dateindex = i;
                        break;
                    }
                }
                if (!datefound)
                {
                    dt.Data_SetField(0, curID);
                    dt.Data_SetField(1, curDate);
                    dt.Data_SetField(2, curTime);
                    dt.Data_SetField(3, "");
                    dtr.Data_AddNew(dt);
                }
                else
                {
                    dtr.Data_Get(dateindex, out dt);
                    dt.Data_SetField(0, curID);
                    dt.Data_SetField(1, curDate);
                    dt.Data_SetField(2, curTime);
                }

            }
            else
            {
                for (int i = 0; i < tmp.Rows.Count; i++)
                {
                    if (tmp.Rows[i][1].ToString().Equals(curDate) && tmp.Rows[i][0].ToString().Equals(curID))
                    {
                        datefound = true;
                        dateindex = i;
                        break;
                    }
                }
                if (!datefound)
                {
                    DataRow[] rows = tmp.Select("fEmpNo = '" + curID + "'");

                    if (rows[rows.Length - 1][2].ToString().Length > 2)
                    {
                        datefound = false;
                        for (int i = 0; i < tmp.Rows.Count; i++)
                        {
                            if (tmp.Rows[i][2].ToString().Equals(rows[rows.Length - 1][2].ToString()) && tmp.Rows[i][0].ToString().Equals(curID))
                            {
                                datefound = true;
                                dateindex = i;
                                break;
                            }
                        }
                        dtr.Data_Get(dateindex, out dt);
                        dt.Data_SetField(0, curID);
                        dt.Data_SetField(1, curDate);
                        dt.Data_SetField(3, curTime);
                    }
                    else
                    {
                        dt.Data_SetField(0, curID);
                        dt.Data_SetField(1, curDate);
                        dt.Data_SetField(2, "");
                        dt.Data_SetField(3, curTime);
                        dtr.Data_AddNew(dt);
                    }
                }
                else
                {
                    dtr.Data_Get(dateindex, out dt);
                    dt.Data_SetField(0, curID);
                    dt.Data_SetField(1, curDate);                  
                    dt.Data_SetField(3, curTime);
                }
            }
            dtr.Script_Add(Script.PROC_NAME, "SAVEDTR");
            dtr.Desc_FileTitle = "MBB_DTR_FILE";
            dtr.Desc_MetaData = "MBB Daily Time Record File";
            dtr.Script_Add(Script.LFFPU_WRITE, dtrfile, "elayorbulc");
            proc.Run(dtr);   
        }*/
        /*void DoDTR()
        {
            DataTable tmp = dtr.ToDataTable();
            UnityElement dt = new UnityElement(dtr.Desc_Fields());
            bool isAdd = false;
            int curIndex = 0;
            DataRow[] rec = tmp.Select("fEmpNo = '" + curID + "'");

            if (rec.Length > 0)
            {
                //Identify the last entry of the current user and extract the index.
                for (int i = 0; i < tmp.Rows.Count; i++)
                {
                    if (tmp.Rows[i][2].ToString().Equals(rec[rec.Length - 1][2].ToString()) && tmp.Rows[i][0].ToString().Equals(curID))
                    {
                        curIndex = i;
                        break;
                    }
                }
                if (isTimeIn)
                {
                    if (tmp.Rows[curIndex][2].ToString().Length > 2 && tmp.Rows[curIndex][1].ToString().Equals(curDate))
                        isAdd = false;
                    else
                        isAdd = true;
                }
                else
                {
                    if (tmp.Rows[curIndex][3].ToString().Length > 2 && tmp.Rows[curIndex][1].ToString().Equals(curDate))
                        isAdd = false;
                    else if (tmp.Rows[curIndex][2].ToString().Length > 2 && tmp.Rows[curIndex][3].ToString().Length < 2)
                        isAdd = false;
                    else
                        isAdd = true;
                }
            }
            else
            {
                isAdd = true;
            }

            if (isAdd)
            {
                dt.Data_SetField(0, curID);
                dt.Data_SetField(1, curDate);
                if (isTimeIn)
                {
                    dt.Data_SetField(2, curTime);
                    dt.Data_SetField(3, "");
                }
                else
                {
                    dt.Data_SetField(2, "");
                    dt.Data_SetField(3, curTime);
                }
                if (rec.Length > 0 && tmp.Rows[curIndex][1].ToString().Equals(curDate))
                {
                    DateTime adjDate = DateTime.Parse(tmp.Rows[curIndex][1].ToString());
                    adjDate = adjDate.AddDays(-1);

                    UnityElement lstDate;
                    dtr.Data_Get(curIndex, out lstDate);
                    lstDate.Data_SetField(1, adjDate.ToString("yyyy-MM-dd"));
                }
                dtr.Data_AddNew(dt);
            }
            else
            {
                dtr.Data_Get(curIndex, out dt);
                if (isTimeIn)
                {
                    dt.Data_SetField(2, curTime);
                }
                else
                {
                    dt.Data_SetField(3, curTime);
                }

            }
            dtr.Script_Add(Script.PROC_NAME, "SAVEDTR");
            dtr.Desc_FileTitle = "MBB_DTR_FILE";
            dtr.Desc_MetaData = "MBB Daily Time Record File";
            dtr.Script_Add(Script.LFFPU_WRITE, dtrfile, "elayorbulc");
            proc.Run(dtr);
        }*/
        void DoDTR()
        {
            DataTable tmp = dtr.ToDataTable();
            UnityElement dt = new UnityElement(dtr.Desc_Fields());
            //bool isAdd = false;
            int curIndex = 0;
            DataRow[] rec = tmp.Select("fEmpNo = '" + curID + "'");

            if (rec.Length == 0)
            {
                dt.Data_SetField(0, curID);
                dt.Data_SetField(1, curDate);
                if (isTimeIn)
                {
                    dt.Data_SetField(2, curTime);
                    dt.Data_SetField(3, "");
                }
                else
                {
                    dt.Data_SetField(2, "");
                    dt.Data_SetField(3, curTime);
                }
                dtr.Data_AddNew(dt);
            }
            else
            {
                //Identify the last entry of the current user and extract the index.
                for (int i = 0; i < tmp.Rows.Count; i++)
                {
                    if (tmp.Rows[i][1].ToString().Equals(rec[rec.Length - 1][1].ToString()) && tmp.Rows[i][0].ToString().Equals(curID))
                    {
                        curIndex = i;
                        break;
                    }
                }
                //Check for already time in and time out.
                UnityElement e;
                dtr.Data_Get(curIndex, out e);
               
                if (isTimeIn)
                {
                    if (e.Data_GetField(1).ToString() == curDate && (e.Data_GetField(2).ToString().Length > 0 || e.Data_GetField(3).ToString().Length > 0))
                    {
                        errType = 1;
                        if (e.Data_GetField(3).ToString().Length > 0) errType = 2;
                        return;
                    }
                    dt.Data_SetField(0, curID);
                    dt.Data_SetField(1, curDate);
                    dt.Data_SetField(2, curTime);
                    dt.Data_SetField(3, "");
                    dtr.Data_AddNew(dt);
                }
                else
                {
                    if (e.Data_GetField(1).ToString() == curDate && e.Data_GetField(3).ToString().Length > 0)
                    {
                        errType = 2;
                        return;
                    }
                    dtr.Data_Get(curIndex, out dt);
                    dt.Data_SetField(3, curTime);
                }
            }
            dtr.Script_Add(Script.PROC_NAME, "SAVEDTR");
            dtr.Desc_FileTitle = "MBB_DTR_FILE";
            dtr.Desc_MetaData = "MBB Daily Time Record File";
            dtr.Script_Add(Script.LFFPU_WRITE, dtrfile, "elayorbulc");
            proc.Run(dtr);
        }

        //UnityProcessor
        void proc_ProcessError(string id, string desc)
        {
            t.SafeCall(this, delegate
            {
                t.SafeCall(this, delegate
                {
                    //MessageBox.Show("An error encountered during operation! Please contact your administrator.", "Terminal", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    MessageBox.Show(desc, "Terminal", MessageBoxButtons.OK, MessageBoxIcon.Error);
                });
            });
        }     
        void proc_ProcessCompleted(string id, string desc)
        {
            t.SafeCall(this, delegate
            {
                switch (id)
                {
                    case "GETPROF":
                        proc.Data_Fetch(out empProf);
                        CheckProfile(curID);
                        if (curFound)
                        {
                            if (isShow)
                            {
                                MainForm.themain.ShowDTR(curID, curName);
                                SetIn();
                                return;
                            }
                            OpenDTR();
                            
                        }
                        else
                        {
                            lblName.Text = "ULIT!";
                            picCurrent.Image = bmp;
                            pnlPop.Visible = true;
                            tmr.Enabled = true;
                            sapi.SpeakAsync("Sorry. Please try again.");
                        }
                        break;
                    case "OPENDTR":
                        proc.Data_Fetch(out dtr);
                        DoDTR();
                        if (errType == 1)
                        {
                            lblName.Text = "ULIT!";
                            picCurrent.Image = bmp;
                            pnlPop.Visible = true;
                            tmr.Enabled = true;
                            sapi.SpeakAsync("Sorry, You already have a time-in");
                        }
                        else if (errType == 2)
                        {
                            lblName.Text = "ULIT!";
                            picCurrent.Image = bmp;
                            pnlPop.Visible = true;
                            tmr.Enabled = true;
                            sapi.SpeakAsync("Sorry, You already have a time out");
                        }
                        errType = 0;
                        break;
                    case "SAVEDTR":
                        lblName.Text = curName;
                        picCurrent.Image = bmp;
                        pnlPop.Visible = true;
                        tmr.Enabled = true;
                        Capture(curName);
                        if (isTimeIn)
                        {
                            if (curID == "0000")
                            {
                                sapi.SpeakAsync("Good Morning Boss!");
                            }
                            else
                            {
                                sapi.SpeakAsync("Welcome to MBB Royal International");
                            }
                        }
                        else
                        {
                            if (curID == "0000")
                            {
                                sapi.SpeakAsync("Thank You Boss!");
                            }
                            else
                            {
                                sapi.SpeakAsync("Good Bye.");
                            }
                        }
                        dtr = new UnityScript("ADD_DTR", new object[] { "fEmpNo", "fDate", "fTimeIn", "fTimeOut" });
                        break;
                }
            });
        }
       
        Bitmap LiveStream()
        {
            if (!cam.IsConnected()) cam.Connect();
            Bitmap bmp = cam.GetBitmap();
            return bmp;
        }
        void Capture(string name)
        {
            if (!cam.IsConnected()) cam.Connect();
            Bitmap bmp = cam.GetBitmap();
            string dateStr = DateTime.Now.ToString("yyyy-MM-dd");
            string timeStr = DateTime.Now.ToString("HH:mm:ss");
            string timeStr2 = DateTime.Now.ToString("HHmmss");
            string act = "In";
            if (!isTimeIn) act = "Out";
            //Post Processing
            Graphics g = Graphics.FromImage(bmp);

            g.DrawString(act + " : " + name + " - " + dateStr + " " + timeStr, new Font("Courier New", 12f, FontStyle.Bold), Brushes.Black, new PointF(10, bmp.Size.Height - 20));
            g.DrawString(act + " : " + name + " - " + dateStr + " " + timeStr, new Font("Courier New", 12f), Brushes.White, new PointF(10, bmp.Size.Height - 20));
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighSpeed;
            g.Save();

            picCurrent.Image = bmp;
            //Save File
            if (!System.IO.Directory.Exists(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\MBB Terminal Data Sec\\"))
                System.IO.Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\MBB Terminal Data Sec\\");

            if (!System.IO.Directory.Exists(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\MBB Terminal Data Sec\\" + dateStr + "\\"))
                System.IO.Directory.CreateDirectory(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\MBB Terminal Data Sec\\" + dateStr + "\\");

            string sec = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\MBB Terminal Data Sec\\" + dateStr + "\\" + timeStr2 + "_" + name;
            picCurrent.Image.Save(sec);
        }
    }
}
